#ifndef __CX_DEVICE_TREE_NANO_H
#define __CX_DEVICE_TREE_NANO_H

/// Use to verify the correctness of the hierarchy
///   31        27        23        19        15        11         7        3      0
/// 0b x x x x | x x x x | x x x x | x x x x | x x x x | x x x x | x x x x | x x x x
///    1 x x x | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  MAIN_ROOT
///
///    1 0 0 0 | 0 0 0 1 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  DMA_ROOT
///    1 0 0 0 | 0 0 0 1 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  DMA_INSTANCE_ROOT
///    1 0 0 0 | 0 0 0 1 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 1  DMA_INSTANCE
///
///    1 0 0 0 | 0 0 1 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  MEMORY_ROOT 
///    1 0 0 0 | 0 0 1 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  MEMORY_INSTANCE_ROOT 
///    1 0 0 0 | 0 0 1 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 1  MEMORY_INSTANCE 
///
///    1 0 0 0 | 0 1 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  STORAGE_ROOT
///    1 0 0 0 | 0 1 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  STORAGE_INSTANCE_ROOT
///    1 0 0 0 | 0 1 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 1  STORAGE_INSTANCE
///
///    1 0 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  DISPLAY_ROOT
///    1 0 0 0 | 1 0 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  DISPLAY_INSTANCE_ROOT
///    1 0 0 0 | 1 0 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 1  DISPLAY_INSTANCE
///
///    1 0 0 1 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  IO_ROOT
///    1 0 0 1 | 0 0 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0  IO_INSTANCE_ROOT
///    1 0 0 1 | 0 0 0 0 | 1 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 1  IO_INSTANCE

/// static device mounted at section("_static_device")

#include <stdint.h>
#include "./ioctl.h"
typedef enum device_tree_node_type
{
    DEVICE_TYPE_MAIN_ROOT = 0x80000000,

    DEVICE_TYPE_DMA_ROOT = 0x81000000,
    DEVICE_TYPE_DMA_INSTANCE_ROOT = 0x81800000,
    DEVICE_TYPE_DMA_INSTANCE = 0x81800001,

    DEVICE_TYPE_MEMORY_ROOT = 0x82000000,
    DEVICE_TYPE_MEMORY_INSTANCE_ROOT = 0x82800000,
    DEVICE_TYPE_MEMORY_INSTANCE = 0x82800001,

    DEVICE_TYPE_STORAGE_ROOT = 0x84000000,
    DEVICE_TYPE_STORAGE_INSTANCE_ROOT = 0x84800000,
    DEVICE_TYPE_STORAGE_INSTANCE = 0x84800001,

    DEVICE_TYPE_DISPLAY_ROOT      = 0x88000000,
    DEVICE_TYPE_DISPLAY_INSTANCE_ROOT      = 0x88800000,
    DEVICE_TYPE_DISPLAY_INSTANCE      = 0x88800001,

    DEVICE_TYPE_IO_ROOT      = 0x90000000,
    DEVICE_TYPE_IO_INSTANCE_ROOT      = 0x90800000,
    DEVICE_TYPE_IO_INSTANCE      = 0x90800001
}device_tree_node_type_t;

typedef struct device_tree_node_base
{
    struct device_tree_node_base *next_partner;
    struct device_tree_node_base *root;
    struct device_tree_node_base *next_level;
    device_tree_node_type_t device_type;
    const char *name;
    void * prob[0];
}device_tree_node_base_t;

typedef struct device_tree_node_io_root
{
    device_tree_node_base_t node_base;
    int (*ioctl)(device_tree_node_base_t *io_instance, enum IOCTL_enum cmd,uint8_t* param, uint16_t len);
}device_tree_node_io_root_t;

typedef struct device_tree_node_io_instance
{
    device_tree_node_base_t node_base;
    void * prob[0];
}device_tree_node_io_instance_t;

#define DEVICE_TREE_NODE_STATIC_MOUNT(node, owner) \
    const device_tree_node_base_t * p_device_tree_##node __attribute__((.section("_static_device"))) = &node; \
    node.root = &owner;
#define DEVICE_TREE_NODE_DYNAMIC_MOUNT(node, owner)
#define DEVICE_TREE_NODE_DYNAMIC_UNMOUNT(node, owner)
 
#endif
